import { Dialog } from 'vant';
import { common } from '@/utils';
import { i18n } from '@/locales';
import EventBus from '@/utils/eventBus';
import Icon from './icon';
import {
  judgeIosPermission,
  requestAndroidPermission,
  gotoAppPermissionSetting,
} from '@/utils/permission';

export default class Scan {
  constructor() {
    this.$t = i18n.global.t;
    common.plusReady(() => {
      this.init();

      this.backView = new window.plus.nativeObj.View('backView', {
        top: '0px',
        left: '5px',
        width: '42px',
        height: '52px',
      });

      const backIcon = new plus.nativeObj.Bitmap('backIcon');
      backIcon.loadBase64Data(Icon['left-arrow'], () => {
        this.backView.drawBitmap(
          backIcon,
          {},
          {
            top: '10px',
            left: '0',
            width: '42px',
            height: '42px',
          },
        );
      });

      this.albumView = new window.plus.nativeObj.View('albumView', {
        top: '0px',
        left: '86%',
        height: '52px',
        width: '42px',
      });

      const photoIcon = new plus.nativeObj.Bitmap('photoIcon');
      photoIcon.loadBase64Data(Icon['image-text'], () => {
        this.albumView.drawBitmap(
          photoIcon,
          {},
          {
            top: '10px',
            left: '0px',
            width: '42px',
            height: '42px',
          },
        );
      });

      this.titleView = new window.plus.nativeObj.View(
        'title',
        {
          top: '0px',
          left: '0px',
          height: '100%',
          width: '100%',
        },
        [
          {
            tag: 'font',
            id: 'scanTitle',
            text: this.$t('richScan'),
            textStyles: {
              size: '18px',
              color: '#ffffff',
            },
            position: {
              top: '10px',
              left: '0px',
              width: '100%',
              height: '40px',
            },
          },
        ],
      );

      this.scanBarView = new window.plus.nativeObj.View(
        'scanBarView',
        {
          top: '68%',
          left: '40%',
          height: '10%',
          width: '22%',
        },
        [this.setScanBarDraw(true)],
      );

      this.codeDictionary = {
        QR: window.plus.barcode.QR,
        CODE128: window.plus.barcode.CODE128,
        EAN13: window.plus.barcode.EAN13,
      };

      this.scanView = window.plus.webview.create(null, 'scanView');

      const currentWebview = window.plus.webview.currentWebview();
      currentWebview.append(this.scanView);

      this.createView(this.scanView);
      this.scanView.hide();
    });
  }

  init() {
    this.flash = false;
    this.barcode = null;
    this.fieldName = null;
  }

  setScanBarDraw(type = true) {
    const scanIcon = new plus.nativeObj.Bitmap('scanIcon');
    scanIcon.loadBase64Data(Icon[type ? 'scan-icon-o' : 'scan-icon'], () => {
      this.scanBarView.drawBitmap(
        scanIcon,
        {},
        {
          left: '36%',
          width: '28%',
          height: '40%',
        },
      );
    });

    return {
      tag: 'font',
      id: 'font',
      text: type ? this.$t('openFlashlight') : this.$t('closeFlashlight'),
      textStyles: {
        size: '16px',
        color: '#ffffff',
      },
      position: {
        top: '10px',
        left: '10%',
        width: '80%',
      },
    };
  }

  show() {
    let result = false;

    if (window.plus.os.name === 'iOS') {
      if (!judgeIosPermission('camera')) {
        result = true;
      }
    } else {
      requestAndroidPermission('android.permission.CAMERA').then(res => {
        if (res !== 1) {
          result = true;
        }
      });
    }

    if (result) {
      return Dialog.alert({
        title: this.$t('hint'),
        message: this.$t('cameraPermissions'),
      }).then(() => {
        gotoAppPermissionSetting();
      });
    }

    this.scanView.show();
    this.createScanView(this.scanView);
  }

  onError(error) {
    window.plus.nativeUI.toast(JSON.stringify(error));
  }

  onMarked(type, result) {
    switch (type) {
      case window.plus.barcode.QR:
        type = 'QR';
        break;
      case window.plus.barcode.CODE128:
        type = 'CODE128';
        break;
      case window.plus.barcode.EAN13:
        type = 'EAN13';
        break;
      default:
        break;
    }

    EventBus.$emit('scan', result.trim(), this.fieldName);
    this.close();
  }

  createScanView(currentWebview) {
    const getBarcode = window.plus.barcode.getBarcodeById('barcode');
    if (!getBarcode) {
      this.barcode = window.plus.barcode.create('barcode', Object.values(this.codeDictionary), {
        top: '0px',
        left: '0px',
        width: '100%',
        height: '100%',
        scanbarColor: '#1e5bc6',
        position: 'static',
        frameColor: '#1e5bc6',
      });
    }
    this.barcode.onmarked = (type, result) => {
      this.onMarked.call(this, type, result);
    };
    this.barcode.onerror = this.onError;
    this.barcode.setFlash(this.flash);
    currentWebview.append(this.barcode);
    this.barcodeInit();
  }

  createView(currentWebview) {
    this.backView.interceptTouchEvent(true);
    this.scanBarView.interceptTouchEvent(true);

    currentWebview.append(this.titleView);
    currentWebview.append(this.scanBarView);
    currentWebview.append(this.backView);
    currentWebview.append(this.albumView);

    this.backView.addEventListener(
      'click',
      () => {
        this.close();
      },
      false,
    );

    this.albumView.addEventListener(
      'click',
      () => {
        let result = false;

        if (window.plus.os.name === 'iOS') {
          if (!judgeIosPermission('photoLibrary')) {
            result = true;
          }
        } else {
          requestAndroidPermission('android.permission.READ_EXTERNAL_STORAGE').then(res => {
            if (res !== 1) {
              result = true;
            }
          });
        }

        if (result) {
          return Dialog.alert({
            title: this.$t('hint'),
            message: this.$t('photoAlbumPermissions'),
          }).then(() => {
            gotoAppPermissionSetting();
          });
        }

        this.galleryImg();
      },
      false,
    );

    this.scanBarView.addEventListener(
      'click',
      () => {
        this.flash = !this.flash;

        if (this.flash) {
          this.scanBarView.draw([this.setScanBarDraw(false)]);
        } else {
          this.scanBarView.draw([this.setScanBarDraw(true)]);
        }

        if (this.barcode) {
          this.barcode.setFlash(this.flash);
        }
      },
      false,
    );
  }

  barcodeInit() {
    this.barcode.cancel();
    this.barcode.start();
  }

  galleryImg() {
    window.plus.gallery.pick(
      path => {
        this.scanImg(path);
      },
      () => {
        this.barcodeInit();
      },
      {
        filter: 'image',
      },
    );
  }

  scanImg(path) {
    window.plus.barcode.scan(
      path,
      (type, result) => {
        this.onMarked.call(this, type, result);
      },
      () => {
        window.plus.nativeUI.toast(this.$t('failToIdentify'));
        this.barcodeInit();
      },
    );
  }

  close() {
    this.barcode.close();
    this.scanView.hide();
    this.barcode.setFlash(false);
    this.scanBarView.draw([this.setScanBarDraw(true)]);
    this.init();
  }
}
